'use strict';

/**
 * JWT认证中间件
 * 验证请求头中的token，确保用户已登录
 * @param {Object} options - 中间件的配置选项
 * @param {Application} app - Egg.js 应用实例
 */
module.exports = (options, app) => {
  return async function auth(ctx, next) {
    // 检查是否在白名单中
    const whitelist = app.config.auth.ignore || [];
    if (whitelist.includes(ctx.path)) {
      await next();
      return;
    }

    // 从请求头获取 Authorization
    const authorization = ctx.get('Authorization');
    if (!authorization) {
      ctx.throw(401, '未登录');
    }

    // 验证 Bearer token 格式
    const parts = authorization.split(' ');
    if (parts.length !== 2) {
      ctx.throw(401, '无效的token格式');
    }

    const scheme = parts[0];
    const token = parts[1];

    // 验证是否使用 Bearer 认证方案
    if (!/^Bearer$/i.test(scheme)) {
      ctx.throw(401, '无效的token格式');
    }

    try {
      // 验证 token 的有效性
      const decoded = ctx.app.jwt.verify(token, app.config.jwt.secret);
      
      // 验证用户是否存在且未被删除
      const person = await ctx.service.person.findById(decoded.person_id);
      if (!person) {
        ctx.throw(401, '用户不存在或已被删除');
      }
      
      // 将解码后的用户信息存储到上下文中，供后续使用
      ctx.state.user = decoded;
      await next();
    } catch (err) {
      // 处理不同类型的token错误
      if (err.name === 'TokenExpiredError') {
        ctx.throw(401, '登录已过期');
      }
      if (err.name === 'JsonWebTokenError') {
        ctx.throw(401, 'token无效');
      }
      if (err.name === 'NotBeforeError') {
        ctx.throw(401, 'token尚未生效');
      }
      // 其他错误直接抛出
      throw err;
    }
  };
}; 